package service

import (
	"encoding/json"
	"fmt"
	"github.com/gofrs/uuid/v5"
	log "github.com/wonderivan/logger"
	"sync"
	"ticket-service/api/apimodel"
	"ticket-service/database/model"
	"ticket-service/httpserver/errcode"
	"ticket-service/pkg/utils/redis"
	"time"
)

func (operator *ResourceOperator) CreateUserOrder(req *apimodel.UserOrderRequest) error {
	var opt model.UserOrder
	var userDB model.User
	var mutex sync.Mutex
	tx, err := operator.TransactionBegin()
	if err != nil {
		log.Error("DeleteTrainSchedule TransactionBegin Error.err[%v]", err)
		return err
	}
	defer func() {
		_ = tx.TransactionRollback()
	}()
	//校验用户ID 以及手机号

	selector := make(map[string]interface{})
	selector[model.FieldID] = req.UserID
	err = tx.Database.ListEntityByFilter(model.TableNameUser, selector, model.OneQuery, &userDB)
	if err != nil {
		log.Error("用户数据查询失败. err:[%v]", err)
		return err
	}

	//校验行驶计划
	var schedule model.TrainSchedule

	selector = make(map[string]interface{})
	selector[model.FieldID] = req.ScheduleID
	err = tx.Database.PreloadEntityByFilter(model.TableNameTrainSchedule, selector, model.OneQuery, &schedule, []string{"Stops", "Seats"})
	if err != nil {
		log.Error("行驶计划数据查询失败. err:[%v]", err)
		return err
	}

	var startInfo, endInfo model.TrainStop
	//校验所属站点
	if schedule.Stops == nil || schedule.Seats == nil {
		log.Error("行驶计划关联座位或停靠信息数据查询失败. err:[%v]", err)
		return err
	}
	for _, v := range schedule.Stops {
		if v.ID == req.StartStationID {
			opt.StartStationID = v.ID
			startInfo = v
		} else if v.ID == req.EndStationID {
			opt.EndStationID = v.ID
			endInfo = v
		}
	}
	if userDB.ID <= 0 {
		return fmt.Errorf(errcode.ErrorMsgSuffixParamNotExists, "用户")
	}
	if schedule.ID <= 0 {
		return fmt.Errorf(errcode.ErrorMsgSuffixParamNotExists, "行驶计划")
	}
	var seatPrice float64
	for _, v := range schedule.Seats {
		if v.SeatType == req.SeatType {
			opt.SeatType = v.SeatType
			seatPrice = v.Price
		}
	}
	if opt.SeatType == "" {
		return fmt.Errorf(errcode.ErrorMsgSuffixParamNotExists, "座位类型")
	}
	if opt.StartStationID <= 0 || opt.EndStationID <= 0 {
		return fmt.Errorf(errcode.ErrorMsgSuffixParamNotExists, "起点或终点")
	}
	opt.UUID = uuid.Must(uuid.NewV4())
	opt.UserID = userDB.ID
	opt.UserPhone = userDB.Phone
	opt.ScheduleID = schedule.ID
	opt.Price = float64(endInfo.StopOrder-startInfo.StopOrder) * seatPrice
	opt.DepartureTime = startInfo.DepartureTime
	opt.ArrivalTime = endInfo.DepartureTime
	opt.StartStation = startInfo
	opt.EndStation = endInfo
	selector = make(map[string]interface{})
	selector[model.FieldScheduleID] = req.ScheduleID
	selector[model.FieldSeatType] = req.SeatType

	//加锁
	mutex.Lock()
	err = tx.Database.ReduceEntityRowsByFilter(model.TableNameTrainSeat, selector, model.OneQuery, "seat_now_nums", "1")
	if err != nil {
		if err.Error() == "NoNums" {
			mutex.Unlock()
			return fmt.Errorf(errcode.ErrorMsgNoTickets, req.SeatType)
		}
		log.Error("座位数量-1失败. err:[%v]", err)
		mutex.Unlock()
		return err
	}
	mutex.Unlock()
	opt.CreatedAt = time.Now()
	//新创建的订单写入redis中
	jsonData, err := json.Marshal(&opt)
	if err != nil {
		log.Error("新增订单 序列化失败 Error.err[%v]", err)
		return err
	}
	_, err = redis.RedisClient.HSet(redisKey, opt.UUID.String(), string(jsonData)).Result()
	if err != nil {
		log.Error("创建订单.写入redis失败 err:[%v]", err)
		return err
	}

	//注册定时任务,写入redis中
	operator.TimerFreeOrder(time.Minute*10, opt)

	err = tx.TransactionCommit()
	if err != nil {
		log.Error("新增订单 TransactionCommit Error.err[%v]", err)
		return err
	}
	return nil
}

func (operator *ResourceOperator) QueryUserOrderList(req *apimodel.UserOrderRequest) (*apimodel.UserOrderPageResponse, error) {
	//@TODO 查找订单：分四类 1待支付 2待出行 3已出行 4已取消 //对应需要参数tag:   WaitingPayList   WaitingDepartList   BeenDepartList   BeenCancelList
	//@TODO 按照order_id查或未输入tag: 返回默认list
	//@TODO 未支付订单按照id、schedule_id、user_id、拆分未完成。
	var resp apimodel.UserOrderPageResponse
	selector := make(map[string]interface{})
	queryParams := model.QueryParams{}
	//订单id查
	if req.ID > 0 {
		selector[model.FieldID] = req.ID
	}
	//user_id查
	if req.UserID > 0 {
		selector[model.FieldUserID] = req.UserID
	}
	//行驶计划查
	if req.ScheduleID > 0 {
		selector[model.FieldScheduleID] = req.ScheduleID
	}
	//创建分组查询条件： 待出行
	if req.Tag == "WaitingDepartList" {
		selector[model.FieldOrderIsPay] = true
		selector[model.FieldOrderIsDepart] = false
	}
	//创建分组查询条件： 已出行
	if req.Tag == "BeenDepartList" {
		selector[model.FieldOrderIsPay] = true
		selector[model.FieldOrderIsDepart] = true
	}
	//创建分组查询条件： 已取消
	if req.Tag == "BeenCancelList" {
		selector[model.FieldOrderIsPay] = true
		selector[model.FieldOrderIsCancel] = true
	}
	if req.Tag == "WaitingPayList" {
		//待支付
		var orders []model.UserOrder
		hashData, err := redis.RedisClient.HGetAll(redisKey).Result()
		if err != nil {
			log.Error("查询订单 待支付订单 Error.err[%v]", err)
			return nil, err
		}
		for _, v := range hashData {
			var order model.UserOrder
			_ = json.Unmarshal([]byte(v), &order)
			orders = append(orders, order)
		}
		//@TODO
		//var targetOrder []model.UserOrder
		//for _, v := range orders {
		//	if req.ScheduleID > 0 {
		//		if req.UserID > 0 {
		//
		//		}
		//
		//	}
		//}
		resp.Load(int64(len(orders)), orders, req.Tag)
		return &resp, nil
	} else if req.Tag == "WaitingDepartList" || req.Tag == "BeenDepartList" || req.Tag == "BeenCancelList" {
		var count int64
		var userOrders []model.UserOrder
		err := operator.Database.CountEntityByFilter(model.TableNameUserOrder, selector, model.OneQuery, &count)
		if err != nil {
			return nil, err
		}
		if count > 0 {
			order := model.Order{
				Field:     model.FieldID,
				Direction: apimodel.OrderDesc,
			}
			queryParams.Orders = append(queryParams.Orders, order)
			if req.PageSize > 0 {
				queryParams.Limit = &req.PageSize
				offset := (req.PageNo - 1) * req.PageSize
				queryParams.Offset = &offset
			}
			err = operator.Database.ListEntityByFilter(model.TableNameUserOrder, selector, queryParams, &userOrders)
			if err != nil {
				log.Error("订单数据查询失败. err:[%v]", err)
				return nil, err
			}
		}
		resp.Load(count, userOrders, req.Tag)
		return &resp, nil
	} else if req.Tag == "" {
		//拼接所有订单。
		var orders []model.UserOrder
		hashData, err := redis.RedisClient.HGetAll(redisKey).Result()
		if err != nil {
			log.Error("查询订单 待支付订单 Error.err[%v]", err)
			return nil, err
		}
		for _, v := range hashData {
			var order model.UserOrder
			_ = json.Unmarshal([]byte(v), &order)
			orders = append(orders, order)
		}

		var count int64
		var userOrders []model.UserOrder
		err = operator.Database.CountEntityByFilter(model.TableNameUserOrder, selector, model.OneQuery, &count)
		if err != nil {
			return nil, err
		}
		if count > 0 {
			order := model.Order{
				Field:     model.FieldID,
				Direction: apimodel.OrderDesc,
			}
			queryParams.Orders = append(queryParams.Orders, order)
			if req.PageSize > 0 {
				queryParams.Limit = &req.PageSize
				offset := (req.PageNo - 1) * req.PageSize
				queryParams.Offset = &offset
			}
			err = operator.Database.ListEntityByFilter(model.TableNameUserOrder, selector, queryParams, &userOrders)
			if err != nil {
				log.Error("订单数据查询失败. err:[%v]", err)
				return nil, err
			}
		}
		userOrders = append(userOrders, orders...)
		resp.Load(count+int64(len(orders)), userOrders, req.Tag)
		return &resp, nil
	} else {
		log.Error("订单 输入tag无效:[%#v]", req.Tag)
		return nil, fmt.Errorf("订单数据 tag输入无效:%s", req.Tag)
	}
}

//
//func (operator *ResourceOperator) DeleteStation(req *apimodel.TrainStationRequest) error {
//	selector := make(map[string]interface{})
//	queryParams := model.QueryParams{}
//	selector[model.FieldID] = req.ID
//	err := operator.Database.DeleteEntityByFilter(model.TableNameStation, selector, queryParams, &model.Station{})
//	if err != nil {
//		log.Error("车站数据删除失败. err:[%v]", err)
//		return err
//	}
//	return nil
//}
//
//func (operator *ResourceOperator) UpdateStation(req *apimodel.TrainStationRequest) error {
//	var opt model.Station
//	//修改车站信息
//	selector := make(map[string]interface{})
//	//校验车站名
//	selector[model.FieldName] = req.Name
//	err := operator.Database.ListEntityByFilter(model.TableNameStation, selector, model.OneQuery, &opt)
//	if err != nil {
//		log.Error("车站名查找失败. err:[%v]", err)
//		return err
//	}
//	if opt.ID > 0 && opt.ID != req.ID {
//		return fmt.Errorf(errcode.ErrorMsgSuffixParamExists, "车站名")
//	}
//
//	selector = make(map[string]interface{})
//	selector[model.FieldStationCode] = req.Code
//	err = operator.Database.ListEntityByFilter(model.TableNameStation, selector, model.OneQuery, &opt)
//	if err != nil {
//		log.Error("车站编码查找失败. err:[%v]", err)
//		return err
//	}
//	if opt.ID > 0 && opt.ID != req.ID {
//		return fmt.Errorf(errcode.ErrorMsgSuffixParamExists, "车站编码")
//	}
//
//	selector = make(map[string]interface{})
//	selector[model.FieldID] = req.ID
//	err = operator.Database.ListEntityByFilter(model.TableNameStation, selector, model.OneQuery, &opt)
//	if err != nil {
//		log.Error("查找车站失败. err:[%v]", err)
//		return err
//	}
//	if opt.ID <= 0 {
//		return fmt.Errorf(errcode.ErrorMsgSuffixParamNotExists, "id")
//	}
//
//	//保持ID不变,暂存createTime（save方法全字段更新）
//	req.ID = opt.ID
//	CreateTime := opt.CreatedAt
//	err = copier.Copy(&opt, req)
//	if err != nil {
//		return err
//	}
//	opt.CreatedAt = CreateTime
//
//	err = operator.Database.SaveEntity(model.TableNameStation, &opt)
//	if err != nil {
//		log.Error("列车数据更新失败. err:[%v]", err)
//		return err
//	}
//	return nil
//}
